import {
  Canvas,
  Group,
  Image,
  Text,
  useCanvasRef,
  useFont,
  useImage
} from "@shopify/react-native-skia";
import {
  forwardRef,
  useCallback,
  useImperativeHandle,
  useState
} from "react";
import { Dimensions, StyleSheet, View } from "react-native";
import { Layer } from "./types";

const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

// 画布状态接口
interface CanvasState {
  layers: Layer[];
  width: number;
  height: number;
  backgroundColor: string;
}

// 自由拼图画布组件属性
interface FreePuzzleCanvasProps {
  onSave?: () => void;
  onCancel?: () => void;
  disabled?: boolean;
  backgroundColor?: string;
  canvasWidth?: number;
  canvasHeight?: number;
}

// 画布操作接口
export interface FreePuzzleCanvasRef {
  // 图层管理
  getLayers: () => Layer[];
  setLayers: (layers: Layer[]) => void;
  addLayer: (layer: Omit<Layer, 'id' | 'zIndex'>) => void;
  removeLayer: (layerId: string) => void;
  toggleLayerVisibility: (layerId: string) => void;
  toggleLayerLock: (layerId: string) => void;
  
  // 内容添加
  addText: (textData: any) => void;
  addSticker: (stickerData: any) => void;
  addImage: (imageData: any) => void;
  
  // 画布操作
  clearCanvas: () => void;
  setBackgroundColor: (color: string) => void;
  
  // 历史记录
  undo: () => void;
  redo: () => void;
  canUndo: () => boolean;
  canRedo: () => boolean;
  
  // 导出
  exportCanvas: () => any;
}

/**
 * 自由拼图画布组件
 * 基于 React Native Skia 实现的画布，支持图层管理、文字、贴纸等功能
 */
const FreePuzzleCanvas = forwardRef<FreePuzzleCanvasRef, FreePuzzleCanvasProps>(
  ({ 
    disabled = false, 
    backgroundColor = "#FFFFFF",
    canvasWidth = screenWidth - 80,
    canvasHeight = screenHeight * 0.6
  }, ref) => {
    const canvasRef = useCanvasRef();
    
    // 画布状态
    const [canvasState, setCanvasState] = useState<CanvasState>({
      layers: [],
      width: canvasWidth,
      height: canvasHeight,
      backgroundColor: backgroundColor,
    });
    
    // 历史记录
    const [history, setHistory] = useState<CanvasState[]>([canvasState]);
    const [historyIndex, setHistoryIndex] = useState(0);
    
    // 容器尺寸
    const [containerSize, setContainerSize] = useState({
      width: canvasWidth,
      height: canvasHeight,
    });

    // 字体管理
    const font = useFont(null, 16);

    // 生成唯一ID
    const generateId = () => {
      return `layer_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    };

    // 保存当前状态到历史记录
    const saveToHistory = useCallback((newState: CanvasState) => {
      const newHistory = history.slice(0, historyIndex + 1);
      newHistory.push(newState);
      setHistory(newHistory);
      setHistoryIndex(newHistory.length - 1);
      setCanvasState(newState);
    }, [history, historyIndex]);

    // 撤销操作
    const undo = useCallback(() => {
      if (historyIndex > 0) {
        const newIndex = historyIndex - 1;
        setHistoryIndex(newIndex);
        setCanvasState(history[newIndex]);
      }
    }, [history, historyIndex]);

    // 重做操作
    const redo = useCallback(() => {
      if (historyIndex < history.length - 1) {
        const newIndex = historyIndex + 1;
        setHistoryIndex(newIndex);
        setCanvasState(history[newIndex]);
      }
    }, [history, historyIndex]);

    // 添加图层
    const addLayer = useCallback((layerData: Omit<Layer, 'id' | 'zIndex'>) => {
      const newLayer: Layer = {
        ...layerData,
        id: generateId(),
        zIndex: canvasState.layers.length,
      };
      
      const newState = {
        ...canvasState,
        layers: [...canvasState.layers, newLayer],
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 添加文字
    const addText = useCallback((textData: any) => {
      const textLayer: Omit<Layer, 'id' | 'zIndex'> = {
        name: '文字',
        type: 'text',
        locked: false,
        visible: true,
        data: {
          text: textData.text || '新文字',
          x: containerSize.width / 2,
          y: containerSize.height / 2,
          fontSize: textData.fontSize || 24,
          color: textData.color || '#000000',
          fontFamily: textData.fontFamily || 'System',
          ...textData,
        },
      };
      
      addLayer(textLayer);
    }, [addLayer, containerSize]);

    // 添加贴纸
    const addSticker = useCallback((stickerData: any) => {
      const stickerLayer: Omit<Layer, 'id' | 'zIndex'> = {
        name: '贴纸',
        type: 'sticker',
        locked: false,
        visible: true,
        data: {
          source: stickerData.source,
          x: containerSize.width / 2,
          y: containerSize.height / 2,
          width: stickerData.width || 100,
          height: stickerData.height || 100,
          ...stickerData,
        },
      };
      
      addLayer(stickerLayer);
    }, [addLayer, containerSize]);

    // 添加图片
    const addImage = useCallback((imageData: any) => {
      const imageLayer: Omit<Layer, 'id' | 'zIndex'> = {
        name: '图片',
        type: 'image',
        locked: false,
        visible: true,
        data: {
          source: imageData.source,
          x: imageData.x || 0,
          y: imageData.y || 0,
          width: imageData.width || 200,
          height: imageData.height || 200,
          ...imageData,
        },
      };
      
      addLayer(imageLayer);
    }, [addLayer]);

    // 切换图层可见性
    const toggleLayerVisibility = useCallback((layerId: string) => {
      const newLayers = canvasState.layers.map(layer =>
        layer.id === layerId ? { ...layer, visible: !layer.visible } : layer
      );
      
      const newState = {
        ...canvasState,
        layers: newLayers,
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 切换图层锁定状态
    const toggleLayerLock = useCallback((layerId: string) => {
      const newLayers = canvasState.layers.map(layer =>
        layer.id === layerId ? { ...layer, locked: !layer.locked } : layer
      );
      
      const newState = {
        ...canvasState,
        layers: newLayers,
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 移除图层
    const removeLayer = useCallback((layerId: string) => {
      const newLayers = canvasState.layers.filter(layer => layer.id !== layerId);
      
      const newState = {
        ...canvasState,
        layers: newLayers,
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 清空画布
    const clearCanvas = useCallback(() => {
      const newState = {
        ...canvasState,
        layers: [],
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 设置背景颜色
    const setBackgroundColor = useCallback((color: string) => {
      const newState = {
        ...canvasState,
        backgroundColor: color,
      };
      
      saveToHistory(newState);
    }, [canvasState, saveToHistory]);

    // 导出画布
    const exportCanvas = useCallback(() => {
      if (canvasRef.current) {
        return canvasRef.current.makeImageSnapshot();
      }
      return null;
    }, [canvasRef]);

    // 渲染文字图层
    const TextLayer = ({ layer }: { layer: Layer }) => {
      if (!layer.visible || layer.type !== 'text') return null;
      
      return (
        <Text
          key={layer.id}
          x={layer.data.x}
          y={layer.data.y}
          text={layer.data.text}
          font={font}
          color={layer.data.color}
        />
      );
    };

    // 渲染贴纸图层
    const StickerLayer = ({ layer }: { layer: Layer }) => {
      const stickerImage = useImage(layer.data.source);
      
      if (!layer.visible || layer.type !== 'sticker' || !stickerImage) return null;
      
      return (
        <Image
          key={layer.id}
          image={stickerImage}
          x={layer.data.x}
          y={layer.data.y}
          width={layer.data.width}
          height={layer.data.height}
        />
      );
    };

    // 渲染图片图层
    const ImageLayer = ({ layer }: { layer: Layer }) => {
      const layerImage = useImage(layer.data.source);
      
      if (!layer.visible || layer.type !== 'image' || !layerImage) return null;
      
      return (
        <Image
          key={layer.id}
          image={layerImage}
          x={layer.data.x}
          y={layer.data.y}
          width={layer.data.width}
          height={layer.data.height}
        />
      );
    };

    // 渲染所有图层
    const renderLayers = () => {
      return canvasState.layers
        .sort((a, b) => a.zIndex - b.zIndex)
        .map((layer) => {
          switch (layer.type) {
            case 'text':
              return <TextLayer key={layer.id} layer={layer} />;
            case 'sticker':
              return <StickerLayer key={layer.id} layer={layer} />;
            case 'image':
              return <ImageLayer key={layer.id} layer={layer} />;
            default:
              return null;
          }
        });
    };

    // 暴露接口
    useImperativeHandle(ref, () => ({
      getLayers: () => canvasState.layers,
      setLayers: (layers: Layer[]) => {
        const newState = { ...canvasState, layers };
        saveToHistory(newState);
      },
      addLayer,
      removeLayer,
      toggleLayerVisibility,
      toggleLayerLock,
      addText,
      addSticker,
      addImage,
      clearCanvas,
      setBackgroundColor,
      undo,
      redo,
      canUndo: () => historyIndex > 0,
      canRedo: () => historyIndex < history.length - 1,
      exportCanvas,
    }), [addLayer, removeLayer, toggleLayerVisibility, toggleLayerLock, addText, addSticker, addImage, clearCanvas, setBackgroundColor, undo, redo, historyIndex, history.length, exportCanvas, saveToHistory, canvasState]);

    return (
      <View
        style={[styles.container, { width: containerSize.width, height: containerSize.height }]}
        onLayout={(event) => {
          const { width, height } = event.nativeEvent.layout;
          setContainerSize({ width, height });
        }}
      >
        <Canvas
          ref={canvasRef}
          style={[styles.canvas, { backgroundColor: canvasState.backgroundColor }]}
        >
          <Group>
            {renderLayers()}
          </Group>
        </Canvas>
      </View>
    );
  }
);

FreePuzzleCanvas.displayName = 'FreePuzzleCanvas';

const styles = StyleSheet.create({
  container: {
    borderRadius: 8,
    overflow: 'hidden',
    backgroundColor: '#FFFFFF',
    borderWidth: 1,
    borderColor: '#E0E0E0',
  },
  canvas: {
    flex: 1,
  },
});

export default FreePuzzleCanvas;
